﻿/* *****************************************************************************
 * @ Encoding: UTF-8
 * @ File Name: naughty_differential.hpp
 * @ Author: cal
 * @ Email: naughtygeng@qq.com
 * @ Created Time: 2022-Jul-06(Wednesday) 11:00:15
 * @ All Rights Reserved
 * *****************************************************************************/

#ifndef NAUGHTY_DIFFERENTIAL_HPP
#define NAUGHTY_DIFFERENTIAL_HPP

#include <memory>
#include <stdint.h>
#include "naughty_differential_node_base.hpp"
#include "naughty_differential_node_var.hpp"
#include "naughty_differential_node_num.hpp"
#include "naughty_differential_node_mul.hpp"
#include "naughty_differential_node_add.hpp"
#include "naughty_differential_node_cos.hpp"
#include "naughty_differential_node_sin.hpp"
#include "naughty_differential_node_pow.hpp"
#include "naughty_differential_node_log.hpp"
#include "naughty_differential_node_ln.hpp"
#include "naughty_differential_node_div.hpp"
#include "naughty_differential_node_exp.hpp"
#include "naughty_differential_node_sub.hpp"

namespace naughty_differential
{

void factorization(std::shared_ptr<node_base> &node_ptr);

void merge_similar_items(std::shared_ptr<node_base> &node_ptr);

void node_sort(std::shared_ptr<node_base> &node_ptr);

void node_optimize(std::shared_ptr<node_base> &node_ptr);
void mul_node_optimize(std::shared_ptr<node_base> &node_ptr);
void add_node_optimize(std::shared_ptr<node_base> &node_ptr);

void val_mul_to_pow(std::shared_ptr<node_base> &node_ptr);

constexpr double e = 2.718281828459045;
constexpr double pi = 3.141592653589793;

}

std::shared_ptr<naughty_differential::node_base> operator+(std::shared_ptr<naughty_differential::node_base> param01, std::shared_ptr<naughty_differential::node_base> param02);
std::shared_ptr<naughty_differential::node_base> operator-(std::shared_ptr<naughty_differential::node_base> param01, std::shared_ptr<naughty_differential::node_base> param02);
std::shared_ptr<naughty_differential::node_base> operator*(std::shared_ptr<naughty_differential::node_base> param01, std::shared_ptr<naughty_differential::node_base> param02);
std::shared_ptr<naughty_differential::node_base> operator/(std::shared_ptr<naughty_differential::node_base> param01, std::shared_ptr<naughty_differential::node_base> param02);
std::shared_ptr<naughty_differential::node_base> operator^(std::shared_ptr<naughty_differential::node_base> param01, std::shared_ptr<naughty_differential::node_base> param02);
std::shared_ptr<naughty_differential::node_base> num(double num);
std::shared_ptr<naughty_differential::node_base> var(std::string val);
std::shared_ptr<naughty_differential::node_base> log(std::shared_ptr<naughty_differential::node_base> param01, std::shared_ptr<naughty_differential::node_base> param02);
std::shared_ptr<naughty_differential::node_base> ln(std::shared_ptr<naughty_differential::node_base> param);
std::shared_ptr<naughty_differential::node_base> exp(std::shared_ptr<naughty_differential::node_base> param);
std::shared_ptr<naughty_differential::node_base> sin(std::shared_ptr<naughty_differential::node_base> param);
std::shared_ptr<naughty_differential::node_base> cos(std::shared_ptr<naughty_differential::node_base> param);

#endif
